//
// Created by 郝羽 on 2018/6/22.
//

#include "ping.hpp"

#include <chrono>
#include <glib.h>

#include "clock.hpp"
#include "config.hpp"
#include "Http.hpp"

struct Pinger {
    pinger_report callback;
    HttpClient http;
    gchar* url;
    guint timer;
    Histogram<int,32> ping_times;
};

gboolean pinger_handle_timeout(gpointer data) {
    auto p = static_cast<Pinger*>(data);
    auto tstart = Clock::now();
    p->http.async_get(p->url, new HttpCallback([p, tstart](int status, const std::string& res) {
        auto now = Clock::now();

        auto ping_time = std::chrono::duration_cast<std::chrono::milliseconds>(
                now - tstart).count();

        g_message("ping time: %d", ping_time);

        p->ping_times.Update(ping_time);

    }));
    return G_SOURCE_CONTINUE;
}

Pinger *pinger_open(Context& ctx) {

    auto p = new Pinger();

    p->url = g_strdup_printf("http://%s/rtc/config", ctx.rtcAddresses[0].c_str());

    p->timer = g_timeout_add(500, pinger_handle_timeout, p);

    p->http.init(nullptr);

    return p;
}

// todo: handle on going ping properly
void pinger_close(Pinger* p) {
    if (p->timer > 0) {
        g_source_remove(p->timer);
        p->timer = 0;
    }
    if (p->url) {
        g_free(p->url);
        p->url = 0;
    }
    delete p;
}

Histogram<int, 32> pinger_result(Pinger* p) {
    auto r = p->ping_times;
    p->ping_times.Clear();
    return r;
}

